#ifndef INCLUDES_AVLTREE_H
#define INCLUDES_AVLTREE_H 1

#include <common/macro/build.h>
#include <common/common.h>

#define AVLTREE_NODE_HEIGHT(node) (node != NULL ? node->depth : (-1))

typedef struct avltree_node_t avltree_node_t;
typedef struct avltree_t {
	avltree_node_t *root;
	int nodes;

	generic_cmp_f         cmp;
} avltree_t;

struct avltree_node_t {
	void *key, *value;

	int depth;
	avltree_node_t *left, *right;
	avltree_node_t *parent;
};

API_LIBLOCAL avltree_t *avltree_new(generic_cmp_f);
API_LIBLOCAL void avltree_destroy(avltree_t *avltree);

API_LIBLOCAL avltree_node_t *avltree_insert(avltree_t *, void *, void *);
API_LIBLOCAL int avltree_delete(avltree_t *, avltree_node_t *);

API_LIBLOCAL avltree_node_t *avltree_search(avltree_t *, void *);
API_LIBLOCAL int avltree_nodes(avltree_t *);

API_LIBLOCAL void *avltree_node_value(avltree_node_t *);
API_LIBLOCAL void *avltree_node_key(avltree_node_t *);

API_LIBLOCAL avltree_node_t *avltree_predecessor(avltree_t *, avltree_node_t *);
API_LIBLOCAL avltree_node_t *avltree_successor(avltree_t *, avltree_node_t *);

#endif
